Skip to content

2690. 无穷方法对象

2690. 无穷方法对象

ts
function createInfiniteObject(): Record<string, () => string> {
   return new Proxy({},{
    get:(target,props)=>{
      return  ()=>props;
    }
   })
};

Proxy 的 get 陷阱

这里直接用到 Proxy 的一个核心能力:拦截属性访问

正常情况下,访问对象不存在的属性会得到 undefined。但有了 get 陷阱,任何属性访问都会被拦截。这里无论访问什么属性名,都返回一个函数,函数被调用时再返回属性名本身。

js
const obj = createInfiniteObject();
obj.hello();  // → "hello"
obj.world();  // → "world"
obj.any.thing.you.want();  // → "want"(最后一次属性访问)

最后一行的行为容易误解。obj.any.thing.you.want() 实际上是:

  1. obj.any → 返回一个函数(但没调用)
  2. .thing → 访问函数的 thing 属性,但函数不是 Proxy,所以 undefined
  3. .you → 同上
  4. .want() → 报错,因为 undefined 不可调用

要让链式调用生效,需要每个属性访问都返回 Proxy:

ts
function createInfiniteObject(): any {
  return new Proxy({}, {
    get: (target, props) => {
      return createInfiniteObject(); // 链式调用的关键
    }
  });
};

这样 obj.a.b.c() 就能递归生成新 Proxy。

为什么这里返回函数而不是递归代理

题目要求 obj.anything() 返回 "anything",也就是把属性名作为字符串返回。递归 Proxy 方案里,obj.a.b.c() 最后只能落到 "c",但 Proxy 本身并不能区分「最后一次属性访问」和「链式调用中间步」。这里用 () 作为终点标记,因此解法选择返回函数。

实际应用

Proxy 的动态属性拦截在前端框架的响应式系统里非常常见(例如 Vue 3 的 track/trigger 依赖追踪),但“无限方法对象”这个具体模式在业务代码里并不常见,更多是一个 Proxy 能力演示。